/**
 * 用户认证管理模块
 * 负责处理登录、登出、窗口转换等认证相关业务
 * @author LYC
 * @date 2025-09-13
 */

import { BrowserWindow, ipcMain } from 'electron'
import { getAppExitManager } from '../app/appExit'

/**
 * 窗口创建回调函数类型
 */
export type WindowCreatorCallback = () => BrowserWindow

/**
 * 认证管理器接口
 */
export interface AuthManagerConfig {
  loginWindowConfig: {
    width: number
    height: number
  }
  mainWindowConfig: {
    width: number
    height: number
    minWidth: number
    minHeight: number
  }
  windowCreators?: {
    createLoginWindow?: WindowCreatorCallback
    createMainWindow?: WindowCreatorCallback
  }
}

/**
 * 用户信息接口
 */
export interface UserInfo {
  username: string
  loginTime: string
  [key: string]: unknown
}

/**
 * 认证状态枚举
 */
export enum AuthState {
  LOGGED_OUT = 'logged_out',
  LOGGING_IN = 'logging_in',
  LOGGED_IN = 'logged_in',
  LOGGING_OUT = 'logging_out'
}

/**
 * 用户认证管理器
 */
export class AuthManager {
  private static instance: AuthManager
  private currentAuthState: AuthState = AuthState.LOGGED_OUT
  private currentUser: UserInfo | null = null
  private config: AuthManagerConfig
  private exitManager = getAppExitManager()

  private constructor(config: AuthManagerConfig) {
    this.config = config
    this.setupIpcHandlers()
  }

  /**
   * 获取单例实例
   */
  public static getInstance(config?: AuthManagerConfig): AuthManager {
    if (!AuthManager.instance) {
      if (!config) {
        throw new Error('AuthManager config is required for first initialization')
      }
      AuthManager.instance = new AuthManager(config)
    }
    return AuthManager.instance
  }

  /**
   * 获取当前认证状态
   */
  public getCurrentAuthState(): AuthState {
    return this.currentAuthState
  }

  /**
   * 获取当前用户信息
   */
  public getCurrentUser(): UserInfo | null {
    return this.currentUser
  }

  /**
   * 检查是否已登录
   */
  public isLoggedIn(): boolean {
    return this.currentAuthState === AuthState.LOGGED_IN
  }

  /**
   * 设置认证状态
   */
  private setAuthState(state: AuthState): void {
    console.log(`Auth state changed: ${this.currentAuthState} -> ${state}`)
    this.currentAuthState = state
  }

  /**
   * 处理登录成功
   */
  public handleLoginSuccess(userInfo: UserInfo): void {
    try {
      this.setAuthState(AuthState.LOGGING_IN)
      this.currentUser = userInfo

      // 获取当前的登录窗口
      const loginWindow = this.exitManager.getActiveWindow()
      if (!loginWindow || loginWindow.isDestroyed()) {
        this.setAuthState(AuthState.LOGGED_OUT)
        return
      }

      // 转换窗口大小和属性
      this.convertLoginWindowToMain(loginWindow)

      // 更新窗口引用
      this.exitManager.setMainWindow(loginWindow)
      this.exitManager.setLoginWindow(null)

      // 重新设置窗口关闭事件
      this.setupMainWindowCloseHandler(loginWindow)

      this.setAuthState(AuthState.LOGGED_IN)
    } catch (error) {
      this.setAuthState(AuthState.LOGGED_OUT)
      this.currentUser = null
      console.error('Error during login process:', error)
    }
  }

  /**
   * 处理登出
   */
  public handleLogout(): void {
    try {
      this.setAuthState(AuthState.LOGGING_OUT)
      // 获取当前的主窗口
      const mainWindow = this.exitManager.getActiveWindow()
      if (!mainWindow || mainWindow.isDestroyed()) {
        console.log('Main window not available, creating new login window...')
        this.createNewLoginWindow()
        this.completeLogout()
        return
      }
      // 转换窗口大小和属性
      this.convertMainWindowToLogin(mainWindow)
      // 更新窗口引用
      this.exitManager.setLoginWindow(mainWindow)
      this.exitManager.setMainWindow(null)

      // 重新设置窗口关闭事件
      this.setupLoginWindowCloseHandler(mainWindow)

      this.completeLogout()
      console.log('Logout process completed successfully')
    } catch (error) {
      console.error('Error during logout process:', error)
      // 即使出错也要清理用户状态
      this.completeLogout()
    }
  }

  /**
   * 完成登出流程
   */
  private completeLogout(): void {
    this.currentUser = null
    this.setAuthState(AuthState.LOGGED_OUT)
  }

  /**
   * 将登录窗口转换为主窗口
   */
  private convertLoginWindowToMain(window: BrowserWindow): void {
    const { mainWindowConfig } = this.config

    window.setSize(mainWindowConfig.width, mainWindowConfig.height)
    window.setMinimumSize(mainWindowConfig.minWidth, mainWindowConfig.minHeight)
    window.setResizable(true)
    window.setMaximizable(true)
    window.setMinimizable(true)
    window.setMovable(true)
    window.center()

    console.log('Window converted to main window size and properties')
  }

  /**
   * 将主窗口转换为登录窗口
   */
  private convertMainWindowToLogin(window: BrowserWindow): void {
    const { loginWindowConfig } = this.config

    window.setSize(loginWindowConfig.width, loginWindowConfig.height)
    window.setResizable(false)
    window.setMaximizable(false)
    window.setMinimizable(false)
    window.setMovable(true)
    window.center()

    console.log('Window converted to login window size and properties')
  }

  /**
   * 设置主窗口关闭事件处理
   */
  private setupMainWindowCloseHandler(window: BrowserWindow): void {
    window.removeAllListeners('close')
    window.on('close', (event) => {
      this.exitManager.handleWindowClose(event, 'main')
    })
  }

  /**
   * 设置登录窗口关闭事件处理
   */
  private setupLoginWindowCloseHandler(window: BrowserWindow): void {
    window.removeAllListeners('close')
    window.on('close', (event) => {
      this.exitManager.handleWindowClose(event, 'login')
    })
  }

  /**
   * 创建新的登录窗口（当主窗口不可用时）
   */
  private createNewLoginWindow(): BrowserWindow | null {
    console.log('Creating new login window...')

    if (this.config.windowCreators?.createLoginWindow) {
      const newWindow = this.config.windowCreators.createLoginWindow()
      this.exitManager.setLoginWindow(newWindow)
      return newWindow
    } else {
      console.error('No login window creator callback provided')
      return null
    }
  }

  /**
   * 创建新的主窗口
   */
  private createNewMainWindow(): BrowserWindow | null {
    console.log('Creating new main window...')

    if (this.config.windowCreators?.createMainWindow) {
      const newWindow = this.config.windowCreators.createMainWindow()
      this.exitManager.setMainWindow(newWindow)
      return newWindow
    } else {
      console.error('No main window creator callback provided')
      return null
    }
  }

  /**
   * 显示主窗口
   */
  public showMainWindow(): void {
    const mainWindow = this.exitManager.getActiveWindow()
    if (mainWindow && !mainWindow.isDestroyed()) {
      mainWindow.show()
      mainWindow.focus()
    } else {
      this.createNewMainWindow()
    }
  }

  /**
   * 显示登录窗口
   */
  public showLoginWindow(): void {
    const loginWindow = this.exitManager.getActiveWindow()
    if (loginWindow && !loginWindow.isDestroyed()) {
      loginWindow.show()
      loginWindow.focus()
    } else {
      this.createNewLoginWindow()
    }
  }

  /**
   * 设置IPC事件处理器
   */
  private setupIpcHandlers(): void {
    // 监听登录成功事件
    ipcMain.on('login-success', (_, userInfo: UserInfo) => {
      this.handleLoginSuccess(userInfo)
    })

    // 监听登出事件
    ipcMain.on('logout', () => {
      this.handleLogout()
    })

    // 监听显示主窗口请求
    ipcMain.on('show-main-window', () => {
      this.showMainWindow()
    })

    // 监听显示登录窗口请求
    ipcMain.on('show-login-window', () => {
      this.showLoginWindow()
    })

    // 获取当前认证状态
    ipcMain.handle('get-auth-state', () => {
      return {
        state: this.currentAuthState,
        user: this.currentUser
      }
    })

    // 获取当前用户信息
    ipcMain.handle('get-current-user', () => {
      return this.currentUser
    })
  }

  /**
   * 清理资源
   */
  public cleanup(): void {
    ipcMain.removeAllListeners('login-success')
    ipcMain.removeAllListeners('logout')
    ipcMain.removeAllListeners('show-main-window')
    ipcMain.removeAllListeners('show-login-window')
    ipcMain.removeHandler('get-auth-state')
    ipcMain.removeHandler('get-current-user')

    // 重置状态
    this.currentUser = null
    this.setAuthState(AuthState.LOGGED_OUT)

    console.log('Auth Manager cleanup completed')
  }

  /**
   * 获取认证统计信息
   */
  public getAuthStats(): {
    state: AuthState
    user: UserInfo | null
    isLoggedIn: boolean
    loginTime?: string
  } {
    return {
      state: this.currentAuthState,
      user: this.currentUser,
      isLoggedIn: this.isLoggedIn(),
      loginTime: this.currentUser?.loginTime
    }
  }
}

/**
 * 获取认证管理器实例
 */
export const getAuthManager = (config?: AuthManagerConfig): AuthManager => {
  return AuthManager.getInstance(config)
}

/**
 * 创建认证管理器配置
 */
export const createAuthConfig = (
  loginWidth: number,
  loginHeight: number,
  mainWidth: number,
  mainHeight: number,
  minWidth: number,
  minHeight: number,
  windowCreators?: {
    createLoginWindow?: WindowCreatorCallback
    createMainWindow?: WindowCreatorCallback
  }
): AuthManagerConfig => {
  return {
    loginWindowConfig: {
      width: loginWidth,
      height: loginHeight
    },
    mainWindowConfig: {
      width: mainWidth,
      height: mainHeight,
      minWidth,
      minHeight
    },
    windowCreators
  }
}
